#ifndef __FS__
#define __FS__

#include <libc.h>
#include <string.h>
#include <types.h>
#include <sched.h>
#include <devices.h>
#include <filesystem-structures.h>

#define NR_DIR 10
#define NR_OPEN_FILES NR_TASKS*NR_CHANNELS // El nombre maxim de fitxers oberts es dona quan tots els processos tenen un fitxer diferent a cada canal


#define DISPLAY_DIR 0
#define KEYBOARD_DIR 1

// ZeOSFAT
#define BLOCK_SIZE 256
#define MAX_BLOCKS 32
#define EOF -1


// File System
extern struct file directory[NR_DIR];
extern struct open_file lsof[NR_OPEN_FILES];

void init_filesystem(void); // Inicialitza tot el sistema de fixters


// Files
int init_open_file(struct task_struct *ts, int fd, int dir, int flags); // Obre un fitxer
int init_new_file(const char *path, int permissions); // Crea un nou file al sistema de fitxers, retorna l'index al directori o ERRNO altrement

int filename_ok(const char *path); // Retorna 0 si el nom es valid, -1 altrement
int find_file(const char *path); // Retorna la posicio del fitxer al directori si existeix, -1 si no existeix
int file_permissions_ok(struct file *f, int mode); // Retorna si es pot accedir a dir amb els permissos indicats

// File sys operations

int sys_open_file(int fd);
int sys_read_file(int fd, char *buffer, int size);
int sys_write_file(int fd, char *buffer, int size);
int sys_close_file(int fd);
int sys_unlink_file(struct file *f);
void sys_init_file(struct file_operations* ops);


// ZeOSFAT
Byte zf_data[MAX_BLOCKS][BLOCK_SIZE];
int zf_allocation_table[MAX_BLOCKS];
int zf_free_block;

int initZeOSFat(void); // Inicialitza la FAT
int zf_get_free_block(void); // Obte el num del primer block lliure, el reserva i actualitza valors, -1 si no n'hi ha
void zf_add_free_blocks(int index); //Allibera la llista enllaçada de blocks que comença a l'index
int zf_get_file_block(int first, int n); //Dona l'index del n-essim block de la llista indexada per first
int zf_next_file_block(int index); //Dona l'index del seguent block del mateix fitxer
int zf_add_file_block(int last); //Afegeix un nou block darrera l'indicat
void zf_file_append_block(int file, int last); // Afegeix un nou block al final de l fitxer


// Devices
void init_devices_files(void); // Crea files al sistema de fitxers per a tots els dispositius


#endif /* __FS__ */
